#include "Chessman.h"
#include "Gameboard.h"

using namespace std;

void Chessman :: change_icon(const string& image_name) {
	icon = new Image(Point(19+cur_i*59,19+cur_j*59),image_name);
}

King :: King(int i, int j,bool col) {
	init_i = cur_i = last_i = i;
	init_j = cur_j = last_j = j;
	choosed = 0;
	color = col;
	turn = col;
	vector<string> tmp;
	tmp.push_back("b_gong.gif");
	tmp.push_back("b_gong_h.gif");
	image_name.push_back(tmp);
	tmp.clear();
	tmp.push_back("r_gong.gif");
	tmp.push_back("r_gong_h.gif");
	image_name.push_back(tmp);
	icon = new Image(Point(19+i*59,19+j*59),image_name[color][0]);
}
bool King :: move_valid(int i, int j, Gameboard& g) {
	if ( (i == cur_i && j == cur_j) || i > 8 || j > 9 || i < 0 || j < 0 )
		return 0;
	if (color)
		return ( i >= (init_i-1) && i <= (init_i+1) && j >= init_j && j <= (init_j+2)
		&& ((abs(i-cur_i) == 1 && j == cur_j) || (abs(j-cur_j) == 1 && i == cur_i)));
	else
		return ( i >= (init_i-1) && i <= (init_i+1) && j <= init_j && j >= (init_j-2)
		&& ((abs(i-cur_i) == 1 && j == cur_j) || (abs(j-cur_j) == 1 && i == cur_i)));
}

bool King :: eat_valid(int i, int j, Gameboard& g) {
	if ( (i == cur_i && j == cur_j) || i > 8 || j > 9 || i < 0 || j < 0 )
		return 0;
	if (color) 
		return ( (i >= (init_i-1) && i <= (init_i+1) && j >= init_j && j <= (init_j+2)
		&& ((abs(i-cur_i) == 1 && j == cur_j) || (abs(j-cur_j) == 1 && i == cur_i)))
		|| (i == cur_i && j >= 7 && j <= 9 && g.get_iconname(i,j,!color) == "b_gong.gif") );
	else
		return ( (i >= (init_i-1) && i <= (init_i+1) && j <= init_j && j >= (init_j-2)
		&& ((abs(i-cur_i) == 1 && j == cur_j) || (abs(j-cur_j) == 1 && i == cur_i)))
		|| (i == cur_i && j >= 0 && j <= 2 && g.get_iconname(i,j,!color) == "r_gong.gif") );
}

Advisor :: Advisor(int i, int j,bool col) {
	init_i = cur_i = last_i = i;
	init_j = cur_j = last_j = j;
	choosed = 0;
	color = col;
	turn = col;
	vector<string> tmp;
	tmp.push_back("b_shi.gif");
	tmp.push_back("b_shi_h.gif");
	image_name.push_back(tmp);
	tmp.clear();
	tmp.push_back("r_shi.gif");
	tmp.push_back("r_shi_h.gif");
	image_name.push_back(tmp);
	icon = new Image(Point(19+i*59,19+j*59),image_name[color][0]);
}

bool Advisor :: move_valid(int i, int j, Gameboard& g) {
	if ( (i == cur_i && j == cur_j) || i > 8 || j > 9 || i < 0 || j < 0 )
		return 0;
	if (color)
		return ( ((j == 0 && i == 3) || (j == 0 && i == 5) || (j == 1 && i == 4)
		|| (j == 2 && i == 3) || (j == 2 && i == 5)) && abs(cur_i-i) == 1 && abs(cur_j-j) == 1 );
	else
		return ( ((j == 7 && i == 3) || (j == 7 && i == 5) || (j == 8 && i == 4)
		|| (j == 9 && i == 3) || (j == 9 && i == 5)) && abs(cur_i-i) == 1 && abs(cur_j-j) == 1 );
}

bool Advisor :: eat_valid(int i, int j, Gameboard& g) {
	return move_valid(i,j,g);
}

Elephant :: Elephant(int i, int j,bool col) {
	init_i = cur_i = last_i = i;
	init_j = cur_j = last_j = j;
	choosed = 0;
	color = col;
	turn = col;
	vector<string> tmp;
	tmp.push_back("b_xiang.gif");
	tmp.push_back("b_xiang_h.gif");
	image_name.push_back(tmp);
	tmp.clear();
	tmp.push_back("r_xiang.gif");
	tmp.push_back("r_xiang_h.gif");
	image_name.push_back(tmp);
	icon = new Image(Point(19+i*59,19+j*59),image_name[color][0]);
}

bool Elephant ::move_valid(int i, int j, Gameboard& g) {
	if ( (i == cur_i && j == cur_j) || i > 8 || j > 9 || i < 0 || j < 0 )
		return 0;
	if (color)
		return ( (j < 5) && ((cur_i-i == 2 && cur_j-j == 2 && !g.pos_available(cur_i-1,cur_j-1))
		|| (cur_i-i == 2 && j-cur_j == 2 && !g.pos_available(cur_i-1,cur_j+1))
		|| (i-cur_i == 2 && cur_j-j == 2 && !g.pos_available(cur_i+1,cur_j-1))
		|| (i-cur_i == 2 && j-cur_j == 2 && !g.pos_available(cur_i+1,cur_j+1))) );
	else
		return ( (j > 4) && ((cur_i-i == 2 && cur_j-j == 2 && !g.pos_available(cur_i-1,cur_j-1))
		|| (cur_i-i == 2 && j-cur_j == 2 && !g.pos_available(cur_i-1,cur_j+1))
		|| (i-cur_i == 2 && cur_j-j == 2 && !g.pos_available(cur_i+1,cur_j-1))
		|| (i-cur_i == 2 && j-cur_j == 2 && !g.pos_available(cur_i+1,cur_j+1))) );
}

bool Elephant :: eat_valid(int i, int j, Gameboard& g) {
	return move_valid(i,j,g);
}

Horse :: Horse(int i, int j,bool col) {
	init_i = cur_i = last_i = i;
	init_j = cur_j = last_j = j;
	choosed = 0;
	color = col;
	turn = col;
	vector<string> tmp;
	tmp.push_back("b_ma.gif");
	tmp.push_back("b_ma_h.gif");
	image_name.push_back(tmp);
	tmp.clear();
	tmp.push_back("r_ma.gif");
	tmp.push_back("r_ma_h.gif");
	image_name.push_back(tmp);
	icon = new Image(Point(19+i*59,19+j*59),image_name[color][0]);
}

bool Horse :: move_valid(int i, int j, Gameboard& g) {
	if ( (i == cur_i && j == cur_j) || i > 8 || j > 9 || i < 0 || j < 0 )
		return 0;
	return ( (abs(cur_i-i) == 1 && cur_j-j == 2 && !g.pos_available(cur_i,cur_j-1)) || (abs(cur_i-i) == 1 && j-cur_j == 2 && !g.pos_available(cur_i,cur_j+1))
		|| (abs(cur_j-j) == 1 && cur_i-i == 2 && !g.pos_available(cur_i-1,cur_j)) || (abs(cur_j-j) == 1 && i-cur_i == 2 && !g.pos_available(cur_i+1,cur_j)) );
}

bool Horse :: eat_valid(int i, int j, Gameboard& g) {
	return move_valid(i,j,g);
}

Chariot :: Chariot(int i, int j,bool col) {
	init_i = cur_i = last_i = i;
	init_j = cur_j = last_j = j;
	choosed = 0;
	color = col;
	turn = col;
	vector<string> tmp;
	tmp.push_back("b_ju.gif");
	tmp.push_back("b_ju_h.gif");
	image_name.push_back(tmp);
	tmp.clear();
	tmp.push_back("r_ju.gif");
	tmp.push_back("r_ju_h.gif");
	image_name.push_back(tmp);
	icon = new Image(Point(19+i*59,19+j*59),image_name[color][0]);
}

bool Chariot :: move_valid(int i, int j, Gameboard& g) {
	if ( (i == cur_i && j == cur_j) || (i != cur_i && j != cur_j) || i > 8 || j > 9 || i < 0 || j < 0 )
		return 0;
	return ( g.check_clear(cur_i,cur_j,i,j)==0 );
}

bool Chariot :: eat_valid(int i, int j, Gameboard& g) {
	return move_valid(i,j,g);
}

Cannon :: Cannon(int i, int j,bool col) {
	init_i = cur_i = last_i = i;
	init_j = cur_j = last_j = j;
	choosed = 0;
	color = col;
	turn = col;
	vector<string> tmp;
	tmp.push_back("b_pao.gif");
	tmp.push_back("b_pao_h.gif");
	image_name.push_back(tmp);
	tmp.clear();
	tmp.push_back("r_pao.gif");
	tmp.push_back("r_pao_h.gif");
	image_name.push_back(tmp);
	icon = new Image(Point(19+i*59,19+j*59),image_name[color][0]);
}

bool Cannon :: move_valid(int i, int j, Gameboard& g) {
	if ( (i == cur_i && j == cur_j) || (i != cur_i && j != cur_j) || i > 8 || j > 9 || i < 0 || j < 0 )
		return 0;
	return ( g.check_clear(cur_i,cur_j,i,j)==0 );
}

bool Cannon :: eat_valid(int i, int j, Gameboard& g) {
	if ( (i == cur_i && j == cur_j) || (i != cur_i && j != cur_j) || i > 8 || j > 9 || i < 0 || j < 0 )
		return 0;
	return ( g.check_clear(cur_i,cur_j,i,j)==1 );
}

Pawn :: Pawn(int i, int j,bool col) {
	init_i = cur_i = last_i = i;
	init_j = cur_j = last_j = j;
	choosed = 0;
	color = col;
	turn = col;
	vector<string> tmp;
	tmp.push_back("b_zu.gif");
	tmp.push_back("b_zu_h.gif");
	image_name.push_back(tmp);
	tmp.clear();
	tmp.push_back("r_zu.gif");
	tmp.push_back("r_zu_h.gif");
	image_name.push_back(tmp);
	icon = new Image(Point(19+i*59,19+j*59),image_name[color][0]);
}

bool Pawn :: move_valid(int i, int j, Gameboard& g) {
	if ( (i == cur_i && j == cur_j) || (i != cur_i && j != cur_j) || i > 8 || j > 9 || i < 0 || j < 0 )
		return 0;
	if ( color ) {
		if ( j <= 3 )
			return 0;
		else {
			if ( cur_j < 5  )
				return ( i == cur_i && j == cur_j + 1 );
			else
				return ( (i == cur_i && j == cur_j + 1) || (j == cur_j && abs(cur_i-i) == 1) );
		}
	}
	if ( !color ) {
		if ( j >= 6 )
			return 0;
		else {
			if ( cur_j > 4 )
				return ( i == cur_i && j == cur_j - 1 );
			else
				return ( (i == cur_i && j == cur_j - 1) || (j == cur_j && abs(cur_i-i) == 1) );
		}
	}
}

bool Pawn :: eat_valid(int i, int j, Gameboard& g) {
	return move_valid(i,j,g);
}